﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using MentalAlchemy.Atomics;

namespace MentalAlchemy.Molecules.NevaAlgorithm.nevamod
{
	/// <summary>
	/// [molecule]
	/// 
	/// Baseline class for operators config.
	/// </summary>
	public abstract class OperatorsConfig
	{
		public const string DEFAULT_FILENAME = "opconf.cfg";

		/// <summary>
		/// [molecule]
		/// 
		/// Load operators config infor from a specified file.
		/// </summary>
		/// <param name="file"></param>
		public abstract void Load(string file);
		public abstract void Save(string file);
	}

	/// <summary>
	/// [molecule]
	/// 
	/// Basic operators configuration. Contains information about:
	/// - operators success rate
	/// - matrix of transitions from one operator to another
	/// </summary>
	public class BasicOperatorsConfig : OperatorsConfig
	{
		public const string TRANS_MATRIX_SEPLINE = "> Transitions matrix:";
		public const char DEFAULT_SEPARATOR = '\t';

		/// <summary>
		/// Succes rate for operators.
		/// </summary>
		public Dictionary<string, float> OpSuccessRate { get; protected set; }

		/// <summary>
		/// Transitions matrix.
		/// 
		/// todo: optimize this if it's really necessary!
		/// </summary>
		public Dictionary<string, Dictionary<string, float>> OpTransitions { get; protected set; }

		#region Overrides of OperatorsConfig
		public override void Load(string file)
		{
			if (!File.Exists(file)) {throw new Exception("File not found ("+ file +")");}

			var lines = File.ReadAllLines(file);

			//
			// read operators success rate.
			OpSuccessRate = new Dictionary<string, float>();
			int i = 0;
			while (string.Compare(lines[i], TRANS_MATRIX_SEPLINE, true) == 0)
			{
				var split = lines[i].Split(DEFAULT_SEPARATOR);
				OpSuccessRate.Add(split[0], float.Parse(split[1]));
				++i;
			}

			//
			// read transitions info.
			// note: +1 due to skip of trans. matrix sep. line.
			for (int j = i+1; j < lines.Length; j++)
			{
				var parts = lines[j].Split(DEFAULT_SEPARATOR);
				OpTransitions.Add(parts[0], new Dictionary<string, float>());

				var tempDict = new Dictionary<string, float>();
				for (int k = 1; k < parts.Length; k+=2)
				{
					tempDict.Add(parts[k], float.Parse(parts[k+1]));
				}
				OpTransitions[parts[0]] = tempDict;

			}
		}

		public override void Save(string file)
		{
			var lines = new List<string>();

			//
			// write operators success rate.
			foreach (var pair in OpSuccessRate)
			{
				lines.Add(pair.Key + DEFAULT_SEPARATOR + pair.Value);
			}
			lines.Add(TRANS_MATRIX_SEPLINE);

			//
			// write transitions matrix.
			foreach (var pair in OpTransitions)
			{
				var line = pair.Key;
				foreach (var valuePair in pair.Value)
				{
					line += DEFAULT_SEPARATOR + valuePair.Key + DEFAULT_SEPARATOR + valuePair.Value;
				}
				lines.Add(line);
			}

			File.WriteAllLines(file, lines.ToArray());
		}
		#endregion
	}
}